'''
from Sodev.pcb import Pcb
from Sodev.handlerPCB import HandlerPCB
'''

class Cpu:
    '''mem, no deberia ser la memoria, si no el memoryAdmin'''
    def __init__(self, mem, clock, handlerPCB):
        self.pc = 0
        self.memoria = mem
        self.clock = clock
        self.interrupted = False
        self.instructionsLeft = 0
        self.handlerPCB = handlerPCB
        self.pcb = None
        
    '''por ahora se asume una memoria lineal'''    
    def executeProc(self,pcb):
        self.interrupted = False
        self.pc = pcb.getPc()
        self.pcb = pcb
        self.clock.setQuantum(pcb.getQuantum())
        
        
    def fetch(self,clock):
        self.clock = clock
        if(not self.interrupted):
            inst = self.memoria.read(self.pc, self.pcb.getPid())
            if(inst != None):
                self.identificarTipoDeInstruccion(inst)
                self.proceder(inst)             
            else:
                '''killpcb (0 intrucciones)'''
                self.pcb.setPc(self.pc)
                self.manejarInterrupcion(0, self.pcb) 
                self.esperarSigPcb()
    
    def timeOut(self,clock):
        if(self.pcb!=None):
            self.pcb.setPc(self.pc)
            self.manejarInterrupcion(1, self.pcb) 
            self.esperarSigPcb()
                   
    def interrupt(self):
        self.interrupted = True
        
    def manejarInterrupcion(self, key, pcb):
        self.handlerPCB.manejarInterrupcion(key,pcb)
        
    '''Identifica entre instr IO y CPU, CPU:Pasa de largo, IO: Provoca un IRQIO'''
    def identificarTipoDeInstruccion(self,inst):
        if(inst.typeOfIntruction()):
            self.pcb.setPc(self.pc)
            pcb = self.pcb
            self.esperarSigPcb()
            self.manejarInterrupcion(2, pcb)
            
    def esperarSigPcb(self):
        self.interrupt()
        self.pcb = None
        self.clock.clockSleep()
    
    def proceder(self,inst):
        #self.instructionsLeft = self.instructionsLeft -1
        if(not inst.typeOfIntruction()):
            self.pc = self.pc + 1   
            print("cpu passed")             


